/**
 *  Copyright (c) 2010-2011, Monash e-Research Centre
 * (Monash University, Australia)
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 * * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *        documentation and/or other materials provided with the distribution.
 * * Neither the name of the Monash University nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.SendFailedException;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import com.sun.mail.smtp.SMTPAddressFailedException;
import com.sun.mail.smtp.SMTPAddressSucceededException;
import com.sun.mail.smtp.SMTPSendFailedException;
import com.sun.mail.smtp.SMTPTransport;

/** 
 * Sends mail through the gmail SMTP server. Uses gmailsender.properties to
 * determine settings / credentials
 *
 * @author Grischa Meyer
 * @author Steve Androulakis
 */
public class GmailSender {

	String to = null;
	String from = null;
	String cc = null;
	String bcc = null;
	String mailhost = null;
	String mailer = "smtpsend";
	String file = null;
	String host = null;
	String user = null;
	String password = null;
	String prot = null;
	String replyto = null;
	boolean debug = false;
	boolean auth = false;
	boolean verbose = false;

	public GmailSender() throws IOException {
		InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("gmailsender.properties");
		Properties props = new Properties();
		props.load(inputStream);

		this.to = props.getProperty("gmailsender.to");

		this.host = props.getProperty("gmailsender.host");
		this.user = props.getProperty("gmailsender.user");
		this.password = props.getProperty("gmailsender.password");
		this.mailhost = props.getProperty("gmailsender.mailhost");
		this.from = props.getProperty("gmailsender.from");
		this.cc = props.getProperty("gmailsender.cc").equals("null") ? null
				: props.getProperty("gmailsender.cc");
		this.bcc = props.getProperty("gmailsender.bcc").equals("null") ? null
				: props.getProperty("gmailsender.bcc");
		this.debug = props.getProperty("gmailsender.debug").equals("true");
		this.verbose = props.getProperty("gmailsender.verbose").equals("true");
		this.auth = props.getProperty("gmailsender.auth").equals("true");
		this.prot = props.getProperty("gmailsender.prot");
		this.replyto = props.getProperty("gmailsender.replyto");
	}

	public static void main(String[] argv) throws IOException {
		GmailSender sender = new GmailSender();
		sender.sendMail("hoa submission2", "hoa message text2", null);

	}
	
	public void sendMail(String subject, String messageText, String to)
	{
		this._sendMail(subject, messageText, to);
	}
	
	public void sendMail(String subject, String messageText)
	{
		this._sendMail(subject, messageText, null);
	}	
	
	private void _sendMail(String subject, String messageText, String to) {
		try {

			Properties props = System.getProperties();
			props.put("mail." + this.prot + ".host", this.mailhost);

			// Get a Session object
			Session session = Session.getInstance(props, null);
			if (this.debug)
				session.setDebug(true);

			/*
			 * Construct the message and send it.
			 */
			Message msg = new MimeMessage(session);
			msg.setFrom(new InternetAddress(this.from));
			
			if (to != null)
			{
				msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(
					to, false));
			}
			else
			{
				msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(
					this.to, false));				
			}
			
			
			if (this.cc != null)
				msg.setRecipients(Message.RecipientType.CC, InternetAddress
						.parse(this.cc, false));
			if (this.bcc != null)
				msg.setRecipients(Message.RecipientType.BCC, InternetAddress
						.parse(this.bcc, false));

			msg.setSubject(subject);

			if (file != null) {
				// Attach the specified file.
				// We need a multipart message to hold the attachment.
				MimeBodyPart mbp1 = new MimeBodyPart();
				mbp1.setText(messageText);
				MimeBodyPart mbp2 = new MimeBodyPart();
				mbp2.attachFile(file);
				MimeMultipart mp = new MimeMultipart();
				mp.addBodyPart(mbp1);
				mp.addBodyPart(mbp2);
				msg.setContent(mp);
			} else {
				// If the desired charset is known, you can use
				// setText(text, charset)
				msg.setText(messageText);
			}

			msg.setHeader("X-Mailer", mailer);
			msg.setHeader("Reply-To", this.replyto);
			msg.setSentDate(new Date());

			// send the thing off
			/*
			 * The simple way to send a message is this:
			 * 
			 * Transport.send(msg);
			 * 
			 * But we're going to use some SMTP-specific features for
			 * demonstration purposes so we need to manage the Transport object
			 * explicitly.
			 */
			SMTPTransport t = (SMTPTransport) session.getTransport(prot);
			try {
				if (auth)
					t.connect(mailhost, user, password);
				else
					t.connect();
				t.sendMessage(msg, msg.getAllRecipients());
			} finally {
				if (verbose)
					System.out
							.println("Response: " + t.getLastServerResponse());
				t.close();
			}

			System.out.println("\nMail was sent successfully.");

		} catch (Exception e) {
			/*
			 * Handle SMTP-specific exceptions.
			 */
			if (e instanceof SendFailedException) {
				MessagingException sfe = (MessagingException) e;
				if (sfe instanceof SMTPSendFailedException) {
					SMTPSendFailedException ssfe = (SMTPSendFailedException) sfe;
					System.out.println("SMTP SEND FAILED:");
					if (verbose)
						System.out.println(ssfe.toString());
					System.out.println("  Command: " + ssfe.getCommand());
					System.out.println("  RetCode: " + ssfe.getReturnCode());
					System.out.println("  Response: " + ssfe.getMessage());
				} else {
					if (verbose)
						System.out.println("Send failed: " + sfe.toString());
				}
				Exception ne;
				while ((ne = sfe.getNextException()) != null
						&& ne instanceof MessagingException) {
					sfe = (MessagingException) ne;
					if (sfe instanceof SMTPAddressFailedException) {
						SMTPAddressFailedException ssfe = (SMTPAddressFailedException) sfe;
						System.out.println("ADDRESS FAILED:");
						if (verbose)
							System.out.println(ssfe.toString());
						System.out.println("  Address: " + ssfe.getAddress());
						System.out.println("  Command: " + ssfe.getCommand());
						System.out
								.println("  RetCode: " + ssfe.getReturnCode());
						System.out.println("  Response: " + ssfe.getMessage());
					} else if (sfe instanceof SMTPAddressSucceededException) {
						System.out.println("ADDRESS SUCCEEDED:");
						SMTPAddressSucceededException ssfe = (SMTPAddressSucceededException) sfe;
						if (verbose)
							System.out.println(ssfe.toString());
						System.out.println("  Address: " + ssfe.getAddress());
						System.out.println("  Command: " + ssfe.getCommand());
						System.out
								.println("  RetCode: " + ssfe.getReturnCode());
						System.out.println("  Response: " + ssfe.getMessage());
					}
				}
			} else {
				System.out.println("Got Exception: " + e);
				if (verbose)
					e.printStackTrace();
			}
		}
	}

}
